package cn.agiledata.bank.common.servlet;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;

import cn.agiledata.bank.hibernateBean.ActionType;
import cn.agiledata.bank.hibernateBean.BankInfo;
import cn.agiledata.bank.hibernateBean.CityInfo;
import cn.agiledata.bank.hibernateBean.ModelType;
import cn.agiledata.bank.hibernateBean.Sysbook;
import cn.agiledata.bank.hibernateBean.SysbookId;

import com.vnv.infrastructure.exception.ErrorCode;
import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBHibernate3BaseMgr;
import com.vnv.infrastructure.service.hibernate3.HibernateService;
 
public class InitForString extends IPBHibernate3BaseMgr {
	public static Map dataDictMap = new HashMap(); // 字典栏目和区间关联的Map

	public static Map mothodCacheMap = new HashMap();// 缓存类方法数组Map 以po名为Key
	/**
	 * 保留旧接口
	 * */
	public static Map getDictionaryMap(){
		return dataDictMap;
	}
	/**
	 * author joe date 2006-03-17 amend date :2006-04-04
	 * by johnny date 2007-02-08
	 * @return
	 */
	 public void init()  {
		try {
			// 获得hibernate模版的子类
			
			HibernateService h3Service = getHibernateService();
			
			// 获得所有的typeid
			List listTypeId = h3Service
					.find("select c.id.typeId,c from Sysbook as c where c.status='1'");
			
			// zln 修正 20080408 取消循环查询SysBook
			// 将数据字典内容按照typeId归类放入Map
			if (listTypeId != null && listTypeId.size() > 0) {
				for (Iterator iter = listTypeId.iterator(); iter.hasNext();) {
					Object[] arrSysbooks = (Object[]) iter.next();
					String strTypeId = (String)arrSysbooks[0];
					List listSysBook;
					if(dataDictMap.get(strTypeId) != null) {
						// Map中已经有相应TypeId数据，添加
						listSysBook = (List)dataDictMap.get(strTypeId);
					}
					else {
						// Map中没有相应TypeId数据，创建
						listSysBook = new ArrayList();
					}
					listSysBook.add(arrSysbooks[1]);
					dataDictMap.put(strTypeId, listSysBook);
				}
			}
			
			// 插入model_type
			List modelTypeList = h3Service
					.find("from ModelType m order by m.id");
			dataDictMap.put("MODEL_TYPE", modelTypeList);
			// 插入action_type
			List actionTypeList = h3Service
					.find("from ActionType a where a.status='1' order by a.id  ");
			dataDictMap.put("ACTION_TYPE", actionTypeList);

			// 个人开放所有银行选择，卡不在银行列表中
			List bankInfoList = h3Service.find("from BankInfo a where a.valid='Y' and a.drawBank=1 and a.bankCode<>'chinaPay' order by a.pri");
			dataDictMap.put("BANK_INFO", bankInfoList);
			
			bankInfoList = h3Service.find("from BankInfo a where a.valid='Y' and a.drawBank=1 and a.bankCode<>'chinaPay' order by a.pri");
			dataDictMap.put("ENTERPRISE_BANK_INFO", bankInfoList);			
			
			List cityInfoList = h3Service.find("from CityInfo where validFlag='Y'");
			dataDictMap.put("CITY_INFO", cityInfoList);
			
			List provinceList = 
				h3Service.find(" from CityInfo s where s.cityLevel = 0 and s.validFlag='Y' order by s.cityId");
			dataDictMap.put("PROVINCE_INFO", provinceList);
			
			// zln 修正 20080408 取消循环查询CityInfo
			// 将城市按照省份归类到Map中
			List listCity = h3Service
					.find("from CityInfo s where s.cityLevel = 1"
							+ " and s.validFlag='Y' order by s.cityId");
			
			if(listCity != null && listCity.size() > 0) {
				for (Iterator iter = listCity.iterator(); iter.hasNext();) {
					CityInfo cityInfo = (CityInfo) iter.next();
					String strProvId = cityInfo.getSupCityId();
					
					List listCityInfo;
					if(dataDictMap.get(strProvId) != null) {
						// Map中已经有相应省份数据，添加
						listCityInfo = (List)dataDictMap.get(strProvId);
					}
					else {
						// Map中没有相应省份数据，创建
						listCityInfo = new ArrayList();
					}
					listCityInfo.add(cityInfo);
					dataDictMap.put(strProvId, listCityInfo);
				}
			}

			// 缓存类方法数组
			initializeMethodCacheMap();

		} catch (DataAccessException e) {
			e.printStackTrace();
		}

	}

	private static List getListByMethod(String typeid, String methodName) {

		List list = null;
		list = getTypeList(typeid);
		if (list == null)
			return null;

		List u = new ArrayList();
		try {
			for (int i = 0; i < list.size(); i++) {
				Object o = invokeGetMethodByCache(list.get(i), methodName);
				if(list.get(i) instanceof Sysbook && methodName.equals("getId")) {
					o = ((SysbookId)o).getListId();
				}
				if (o == null) {
                    u.add(list.get(i));
                } else {
                    u.add(o);
                }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return u;

	}
	
	private static Object invokeGetMethodByCache(Object instance,String methodName)throws IPBException{
		  try {
			  String className=instance.getClass().getName();
			  String cName =className.substring(className.lastIndexOf(".")+1,className.length());
			  
			 if( getMethodByCache( cName,methodName)==null)return null;
			  
	            Method method =getMethodByCache( cName,methodName);
	            
	            return method.invoke(instance,new Object[]{});
	        }
	        catch (Exception e) {
	          
	            String[] params = {methodName, instance.getClass().getName()};
	            throw new IPBException(ErrorCode.INVOKE_METHOD_ERROR, params, e);
	        }
	}

	public static List getTypeList(String typeid) {
		List list = null;
		Map m = InitForString.dataDictMap;
		if (m == null && m.get(typeid) == null)
			return null;
		list = (ArrayList) m.get(typeid);
		return list;
	}

	public static List getListByField(String typeid, String field)
			 {
		String methodName = "get" + field.substring(0, 1).toUpperCase()
				+ field.substring(1, field.length());
		return getListByMethod(typeid, methodName);

	}

	public static List getListId(String typeid) {
		if (typeid == null)
			return null;
		if (typeid.equals("ACTION_TYPE"))
			return getListByField(typeid, "id");
		else if (typeid.equals("MODEL_TYPE"))
			return getListByField(typeid, "id");
		else if (typeid.equals("BANK_INFO"))
			return getListByField(typeid, "id");
		else if (typeid.equals("ENTERPRISE_BANK_INFO"))
			return getListByField(typeid, "id");
		else if (typeid.equals("CITY_INFO"))
			return getListByField(typeid, "cityId");
		else if(typeid.equals("PROV_LIST")){
			return _getProvIdList();
		}
		else if(dataDictMap.get(typeid)!=null)
			return getListByField(typeid, "id");
		
		
		return null;
	}
	public static List getListName(String typeid) {

		if (typeid == null)
			return null;
		if (typeid.equals("ACTION_TYPE"))
			return getListByField(typeid, "actionName");
		else if (typeid.equals("MODEL_TYPE"))
			return getListByField(typeid, "modelName");
		else if (typeid.equals("BANK_INFO"))
			return getListByField(typeid, "bankName");
		else if (typeid.equals("ENTERPRISE_BANK_INFO"))
			return getListByField(typeid, "bankName");
		else if (typeid.equals("CITY_INFO"))
			return getListByField(typeid, "cityName");
		else if(typeid.equals("PROV_LIST")){
			return _getProvNameList();
		}
		else if(dataDictMap.get(typeid)!=null)
			return getListByField(typeid, "listName");
		return null;
	}

	private static void initializeMethodCacheMap() {
		mothodCacheMap.put("ActionType", ActionType.class.getMethods());
		mothodCacheMap.put("ModelType", ModelType.class.getMethods());
		mothodCacheMap.put("BankInfo", BankInfo.class.getMethods());
		mothodCacheMap.put("Sysbook", Sysbook.class.getMethods());
		mothodCacheMap.put("CityInfo", CityInfo.class.getMethods());
	}

	public static Method getMethodByCache(String key, String methodName) {
		if(mothodCacheMap.get(key)==null)return null;
		Method[] methods = (Method[]) mothodCacheMap.get(key);
		for (int i = 0; i < methods.length; i++) {
			if (methods[i].getName().equalsIgnoreCase(methodName)) {
				return methods[i];
			}
				
		}
		return null;
	}
	
	private static List _getProvIdList(){
		
		List  l= getListId("CITY_INFO");
		List list =new ArrayList();
		for(int i=0;i<l.size();i++){
			if(l.get(i).toString().length()==2)
				list.add(l.get(i));
		}
		return list;
	}
	
	private static List _getProvNameList(){
		
		List  l= getListId("CITY_INFO");
		List  n= getListName("CITY_INFO");
		List list =new ArrayList();
		for(int i=0;i<l.size();i++){
			if(l.get(i).toString().length()==2)
				list.add(n.get(i));
		}
		return list;
	}
}
